<?php
// +----------------------------------------------------------------------
// | zlserver [ 小程序 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2018 http://www.zhongliansoft.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: tony <tanyu@zhongliansoft.com>
// +----------------------------------------------------------------------
namespace app\job\import;

use think\exception\ErrorException;
use think\facade\Validate;
use think\queue\Job;
use app\common\model\User as UserModel;
use app\common\model\ManageUserRole as ManageUserRoleModel;
use app\common\model\ManageUserRoleRel as ManageUserRoleRelModel;
use app\common\model\Dept as DeptModel;
use app\common\model\Position as PositionModel;

use app\common\model\Ietask;
use think\facade\Log;

class User
{
    protected $rule = [
        //'username' => 'require|max:40',
        'truename' => 'require|max:40',
        //'password' => 'require|min:6',
        //'role' => 'require|in:集团领导,教职工,财务人员,维修人员,学生',
        //'mobile' => 'require',
        'sex' => 'require|in:男,女', 
        'dept' => 'require|max:40', 
        'position' => 'require|max:40', 
        'status' => 'require|in:正常,停用'
    ];
    protected $msg = [
        //'username.require' => '账号必填',
        //'username.max' => '账号最长40个字符',
        'truename.require' => '姓名必填',
        'truename.max' => '姓名最长40个字符',
        'position.require' => '职位必填',
        'position.max' => '职位最长40个字符',
        'dept.require' => '部门必填',
        'dept.max' => '部门最长40个字符',
        // 'password.require' => '密码必须',
        // 'password.alphaNum' => '密码格式错误',
        //'role.require' => '角色必填',
        //'role.in'      => '角色类型错误:请参考模板角色类型介绍，或咨询系统管理员',
        //'mobile.require' => '请输入一个合法的手机号码', 
        'sex.in' => '性别类型错误:请参考模板性别类型介绍，或咨询系统管理员',
        'sex.require' => '性别必填',
        'status.in' => '状态类型错误:请参考模板状态类型介绍，或咨询系统管理员',
        'status.require' => '状态必填'
    ];

    // 数据校验
    public function check($fileId, $filePath)
    {
        $re = [
            'count' => 0,
            'code' => 0,
            'msg' => ''
        ];

        $userModel = new UserModel();
        $deptModel = new DeptModel();
        $positionModel = new PositionModel();
        $manageUserRoleModel = new ManageUserRoleModel();
        $data = [];
        $errorData = [];
        try {
            // $csv = new \org\Csv();
            // $resCsv = $csv->import($filePath);

            $resXls=import_excel($filePath);  

            if ($resXls['status']) {
                // 清理导入提示
                unset($resXls['data'][0]);
                // 取表头
                $header = $resXls['data'][1];
                unset($resXls['data'][1]);
                $title = $userModel->csvHeader();
                $title[] = [
                    'id'   => 'role',
                    'desc' => '角色',
                ];
                $fields = [];

                // 遍历表头
                $last_index = 0;
                foreach ($title as $key => $val) {
                    // 从导入的数据表中查找字段位置
                    $index = array_search($val['desc'], $header);
                    if ($index !== false) {
                        $fields[] = [
                            'index' => $index,
                            'value' => $val['id']
                        ];
                    }
                    $last_index = $index;
                }
 
                if(count($fields) != 7) { 
                    $re['msg']  = '文件格式错误！请先下载导入模板，按模板要求准备导入数据后再次导入！';
                    $re['code']  = -1;
                    return $re;
                } else {

                    // 数据填充
                    $iData = [];
                    if ($fields) {
                        $i = 0;
                        foreach ($resXls['data'] as $key => $val) {
                            foreach ($fields as $fkey => $fval) {
                                $iData[$i][$fval['value']] = $val[$fval['index']];
                                if(is_object($iData[$i][$fval['value']])) {
                                    $iData[$i][$fval['value']] = $iData[$i][$fval['value']]->__toString();
                                }
                            }
                            $i++;
                        }
                    }
    
                    // 增加描述字段
                    $fields[] = [
                        'index' => $last_index + 1,
                        'value' => 'desc'
                    ];
                    
                    $count = count($iData);
                    $errCount = 0;
    
                    $mobileList = $userModel->getMobileList(); 
                    $deptModelList = $deptModel->getDeptList(); 
                    $positionList = $positionModel->getPositionList(); 
                    $userRoleList = $manageUserRoleModel->getUserRoleList();
                    
                    $tmp_arr = array(); 
                    // 数据预处理 
                    foreach ($iData as $key => $val) {
                        $errFind = false;
                        //校验数据
                        $validate = new \think\Validate($this->rule, $this->msg);
                        $validate->batch(true);

                        // 数据预处理
                        $time = time();
                        $user['username'] = trim($val['mobile']) == null ? '' : $val['mobile'];
                        $user['truename'] = trim($val['truename']);
                        $user['dept'] = trim($val['dept']);
                        $user['position'] = trim($val['position']);
                        $user['role'] = trim($val['role']);
                        $user['mobile'] = trim($val['mobile']);
                        $user['sex'] = trim($val['sex']);
                        $user['status'] = trim($val['status']);
                        $user['desc'] = '';
                        $user['error'] = 0;
 
                        if (!$validate->check($user)) {
                            $user['error'] = 1;
                            $errCount = $errCount + 1;
                            $errFind = true;

                            $index = 0;
                            foreach ($validate->getError() as $errKey => $value) {
                                if($index == 0) {
                                    $user['desc']  = $user['desc'] . $value;
                                } else {
                                    $user['desc']  = $user['desc'] . ';' . $value;
                                }
                                $index++;
                            }  
                        }

                        // 分隔符确认
                        if (strlen($user['role']) == 0) {
                            $user['error'] = 1;  
 
                            if($errFind) {
                                $user['desc'] =  $user['desc'] . ';' . '角色不能为空';
                            } else {
                                $errCount = $errCount + 1;
                                $errFind = true;
                                $user['desc'] =  '角色不能为空';
                            }
                        } else if (strpos($user['role'], '；') !== false || strpos($user['role'], '、') !== false || strpos($user['role'], '，') !== false) {
                            $user['error'] = 1; 
                            
                            if($errFind) {
                                $user['desc'] =  $user['desc'] . ';' . '多角色分割符号错误，请使用英文[;]';
                            } else {
                                $errCount = $errCount + 1;
                                $errFind = true;
                                $user['desc'] =  '多角色分割符号错误，请使用英文[;]';
                            }
                        } else {
                            $keywords = preg_split("/[\s;]+/", $user['role']);
  
                            $roleIndex = 1;
                            foreach($keywords as $roleV) {
                                $user['role'] = trim($roleV);

                                // 这里角色需要进行实际的校验，
                                if (!array_key_exists($user['role'], $userRoleList)) { 
                                    // 数据库检测
                                    $user['error'] = 1; 
                                    if($errFind) {
                                        if(count($keywords) == 1) {
                                            $user['desc']  = $user['desc'] . ';' . '角色类型错误:请参考模板角色类型介绍，或咨询系统管理员'; 
                                        } else {
                                            $user['desc']  = $user['desc'] . ';' . '第' . $roleIndex . '个角色类型错误:请参考模板角色类型介绍，或咨询系统管理员'; 
                                        }
                                    } else {
                                        $errCount = $errCount + 1;
                                        $errFind = true;
                                        if(count($keywords) == 1) {
                                            $user['desc'] =  '角色类型错误:请参考模板角色类型介绍，或咨询系统管理员';
                                        } else {
                                            $user['desc'] =  '第' . $roleIndex . '个角色类型错误:请参考模板角色类型介绍，或咨询系统管理员';
                                        } 
                                    }
                                }

                                $roleIndex++;
                            }
                        }

                        $user['role'] = trim($val['role']);
                        
                        // 判断手机号是否重复
                        if (in_array($user['mobile'], $mobileList)) {
                            $user['error'] = 1;

                            if($errFind) {
                                $user['desc'] =  $user['desc'] . ';' . $user['username'] . '手机号码已存在';
                            } else {
                                $errCount = $errCount + 1;
                                $errFind = true;
                                $user['desc'] =  $user['username'] . '手机号码已存在';
                            }
                        }

                        // 判断账号是否重复
                        // if (in_array($user['username'], $usernameList)) {
                        //     $user['error'] = 1;

                        //     if($errFind) {
                        //         $user['desc'] =  $user['desc'] . ';' . $user['username'] . '账号已存在';
                        //     } else {
                        //         $errCount = $errCount + 1;
                        //         $errFind = true;
                        //         $user['desc'] =  $user['username'] . '账号已存在';
                        //     }
                        // }

                        // 判断部门是否存在
                        if ($user['dept'] != '' && !in_array($user['dept'], $deptModelList)) {
                            $user['error'] = 1;

                            if(strpos($user['desc'], '部门') === false) { 
                                if($errFind) {
                                    $user['desc'] =  $user['desc'] . ';' . '部门不存在';
                                } else {
                                    $errCount = $errCount + 1;
                                    $errFind = true;
                                    $user['desc'] =  '部门不存在';
                                }
                            }
                        }

                        // 判断职位是否重复
                        if ($user['position'] != '' && !in_array($user['position'], $positionList)) {
                            $user['error'] = 1;

                            if(strpos($user['desc'], '职位') === false) { 
                                if($errFind) {
                                    $user['desc'] =  $user['desc'] . ';' . '职位不存在';
                                } else {
                                    $errCount = $errCount + 1;
                                    $errFind = true;
                                    $user['desc'] =  '职位不存在';
                                }
                            }
                        }

                        // 手机号检测 /^1[34578]{1}\d{9}$/
                        if(!preg_match("/^1[3|4|5|6|7|8|9][0-9]\d{8}$/", $user['mobile'])) {
                            $user['error'] = 1;
                            if(strpos($user['desc'], '手机号码') === false) { 
                                if($errFind) {
                                    $user['desc'] =  $user['desc'] . ';' . '请输入一个合法的手机号码';
                                } else {
                                    $errCount = $errCount + 1;
                                    $errFind = true;
                                    $user['desc'] =  $user['desc'] . '请输入一个合法的手机号码';
                                }
                            }
                        }
    
                        // 自身检测
                        if (in_array($user['username'], $tmp_arr)) { //搜索$v[$key]是否在$tmp_arr数组中存在，若存在返回true
                            $user['error'] = 1;
                            if($errFind) {
                                $user['desc'] = $user['desc'] . ';' . '导入数据中手机号重复'; 
                            } else {
                                $errCount = $errCount + 1;
                                $errFind = true;
                                $user['desc'] = $user['desc'] . '导入数据中手机号重复'; 
                            }
                        } else {
                            if($user['username'] != '') {
                                $tmp_arr[] = $user['username'];
                            }
                        }

                        if ($user['error'] == 1) {
                            $errorData[$errCount - 1] = $user;
                        }
    
                        $data[$key] = $user;
                        unset($user);
                    }
                } 
            } else {
                $re['msg']  = $resCsv['msg'];
                $re['code']  = -1;
                return $re;
            }
        } catch (Exception $e) {
            $re['msg']  = $e->getMessage();
            $re['code']  = -1;
            return $re;
        }

        $re['count'] = $count;
        $re['errCount'] = $errCount;
        $re['data'] = json_encode($data);
        $re['fileId'] = $fileId;
        $re['filePath'] = $filePath;
        $re['errData'] = json_encode($errorData);
        return $re;
    }

    //执行导入任务
    public function exec(Job $job, $params)
    {
        $ietaskModle = new Ietask();
        $userModel = new UserModel();
        $deptModel = new DeptModel();
        $positionModel = new PositionModel();
        $manageUserRoleModel = new ManageUserRoleModel();
        $message = [];
        $count = 0;         // 记录总数
        $progress = 0;
        try {
            $file = json_decode($params['params'], true);
            //$csv = new \org\Csv();
            //$resCsv = $csv->import($file['file_path']);
 
            $resXls=import_excel($file['file_path']); 
            $count = count($resXls['data'])-2;

            if ($resXls['status']) {
                // 清理导入提示
                unset($resXls['data'][0]);
                // 取表头
                $header = $resXls['data'][1];
                unset($resXls['data'][1]);
                $title = $userModel->csvHeader(); 
                $title[] = [
                    'id'   => 'role',
                    'desc' => '角色',
                ];
                $fields = [];

                foreach ($title as $key => $val) {
                    $index = array_search($val['desc'], $header);
                    if ($index >= 0) {
                        $fields[] = [
                            'index' => $index,
                            'value' => $val['id']
                        ];
                    }
                }
                $iData = [];
                if ($fields) {
                    $i = 0;
                    foreach ($resXls['data'] as $key => $val) {
                        foreach ($fields as $fkey => $fval) {
                            $iData[$i][$fval['value']] = $val[$fval['index']];
                            if(is_object($iData[$i][$fval['value']])) {
                                $iData[$i][$fval['value']] = $iData[$i][$fval['value']]->__toString();
                            }
                        }
                        $i++;
                    }
                }
 
                $time = time();
                $defaultPwd = md5(md5('123123') . $time);

                //查询评价商品
                unset($user_comment);
                $user_comment = [];
 
                $user_role_array = [];  // 用于插入角色信息
                $username_array = [];   // 用于判断是否本地导入内容

                $userRoleList = $manageUserRoleModel->getUserRoleList();
                foreach ($iData as $key => $val) {
                    $keywords = preg_split("/[\s;]+/", $val['role']);
                    
                    foreach($keywords as $roleV) {
                        $user_role_array[strval($val['username'])][] = $userRoleList[trim($roleV)];
                    }

                    $sex = $userModel::SEX_BOY;
                    $val['sex'] = trim($val['sex']);
                    if ($val['sex'] == '男') {
                        $sex = $userModel::SEX_BOY;
                    } elseif ($val['sex'] == '女') {
                        $sex = $userModel::SEX_GIRL;
                    } else {
                        $sex = $userModel::SEX_OTHER;
                    }

                    $status = trim($val['status']) == '正常' ? $userModel::STATUS_NORMAL : $userModel::STATUS_DISABLE; 

                    $user_comment[] = [
                        'username'    => trim($val['username']),
                        'truename'  => trim($val['truename']),
                        'deptId'  => $deptModel->getIdByName(trim($val['dept'])),
                        'positionId'  => $positionModel->getIdByName(trim($val['position'])),
                        'password' => $defaultPwd,
                        'mobile' => trim($val['mobile']),
                        'sex'    => $sex,
                        'status'  => $status,
                        'ctime'    => $time,
                        'utime'    => $time,
                    ];
    
                    if (!in_array(trim($val['username']), $username_array)) {
                        $username_array[] = trim($val['username']);
                    }

                    // 每隔100条数据更新一次数据处理进度
                    $progress++; 
                    if($progress %100==0) {
                        // 批量插入数据
                        $userModel->startTrans(); 
                        $num = $userModel->insertAll($user_comment);
                        if($num != 100) {
                            $userModel->rollback();
                            Log::record($user_comment . '用户数据保存失败');
                        } else {                        
                            $userModel->commit();
                        }

                        // 清理环境
                        unset($user_comment);
                        $user_comment = [];
                    }
                }

                // 批量插入数据
                $userModel->startTrans(); 
                $num = $userModel->insertAll($user_comment);               
                $userModel->commit(); 
 
                // 批量更新角色信息
                $userRoleModel = new ManageUserRoleRelModel();
                $userInfoList = $userModel->getIDAndUsernameList(); 
                
                //角色信息
                $jobProgress = 0;
                unset($user_job_comment);
                $user_job_comment = [];

                foreach ($userInfoList as $jobKey => $jobVal) {
                    // 首先判断是否是本次导入的数据
                    if(in_array($jobVal['username'], $username_array)) {
                        foreach ($user_role_array[$jobVal['username']] as $vrole) {
                            $user_job_comment[] = [
                                'manage_id'    => $jobVal['id'],
                                'role_id'  => $vrole
                            ];

                            // 每隔100条数据更新一次数据处理进度
                            $jobProgress++; 
                            if($jobProgress %100==0) {
                                // 批量插入数据
                                $userRoleModel->startTrans(); 
                                $num = $userRoleModel->insertAll($user_job_comment);
                                if($num != 100) {
                                    $userRoleModel->rollback();
                                    Log::record($user_job_comment . '用户数据保存失败');
                                } else {                        
                                    $userRoleModel->commit();
                                }
        
                                // 清理环境
                                unset($user_job_comment);
                                $user_job_comment = [];
                            }    
                        }
                    } 
                }
   
                // 批量插入数据
                $userRoleModel->startTrans(); 
                $num = $userRoleModel->insertAll($user_job_comment);               
                $userRoleModel->commit(); 

                $uData['status'] = $ietaskModle::IMPORT_SUCCESS_STATUS;
                $uData['message'] = '导入成功';
                if ($message) {
                    $uData['message'] .= json_encode($message);
                }

                $uData['count'] = $count;
                $ietaskModle->update($uData, ['id' => $params['task_id']]);
            } else {
                $uData['status'] = $ietaskModle::IMPORT_FAIL_STATUS;
                $uData['message'] = $resXls['msg'];
                $uData['utime'] = time();
                $ietaskModle->update($uData, ['id' => $params['task_id']]);
            }
        } catch (Exception $e) {
            $message[] = $e->getMessage();
        }
        if ($job->attempts() > 3) {
            $uData['status'] = $ietaskModle::IMPORT_FAIL_STATUS;
            $uData['message'] = '导入执行失败';
            $uData['utime'] = time();
            $ietaskModle->update($uData, ['id' => $params['task_id']]);
            $job->delete();
        }
    }

    public function failed($data)
    {

        // ...任务达到最大重试次数后，失败了
    }
}
